#include <iostream>
#include <windows.h>
#include <conio.h>
#include "Const.h"


//��������������� ��������� �������� ���������� ����.
void init_game(Field& field, Snake& snake, Game& game, Food& food)//��������������� ��������� �������� ���������� ����.
{	
	food.score = 0;//���������� ��������� ���
	food.food_flag = false;//�������, ��� ��� �����������
	game.timeout = 100; //������� �������� ����� ������ ����; > 100 (ms), 1000 - ����� ����������� ���������� ��������� �� 1 �������
	game.game_on = 1;//������� ����������� ����
	snake.direction = turn_right;

	srand(time(0));//��������� ������ ������������������, ������������ �������� rand() 	

	system("cls");//������ ������� �������

	create_field(field);//C������� ���������� ������������� ������� ���� �� ������ ���������������� ������

	start_snake(field, snake);//��������������� ��������� ��������� ������ ������ ��� ������ ���� � ����������� �� ������� ���� (�� ������)

	init_snake(snake);//��������������� ���������������� ������ ������, ������ ������ ����������� ���������� ����������
	
	init_field(field);//�������������  ���� (������� ���������� ���� � ������)

	set_snake(field, snake);//������ ��������������� � ������� ����

	print_field(field, food.score);//������ ����

	std::cout << "Press any key" << std::endl;//5)	����� ����������� � ����.
}

//��������������� ��������� ��������� ������ ������ ��� ������ ���� � ����������� �� ������� ���� (�� ������)
void start_snake(Field& field, Snake& snake)
{
	//int step_x = rand() % L + 1; // ����������� ��������� ��������� ��������� ������ 
	//step = 13;
	//snake_x[0] = 13;

	snake.snake_x[0] = field.columns / 2;
	snake.snake_y[0] = field.rows / 2;
}

//������ ��������������� � ������� ����
void set_snake(Field& field, Snake& snake)
{	
	field.field[snake.snake_y[0]][snake.snake_x[0]] = head_symbol;//��������� ������

		// ��������� ������, ���� ����
		
		for (int i = 1; i < snake.snake_size; i++)
		{			
			field.field[snake.snake_y[i]][snake.snake_x[i]] = tail_symbol;
		}	
}

//��������� ������� ������ �� ����
void clear_snake(Field& field, Snake& snake)
{
	//������ "�����"
	field.field[snake.snake_y[snake.snake_size-1]][snake.snake_x[snake.snake_size-1]] = field_symbol;
}

// ������������ �������� ��� � ��������������� � ������� ����.
void set_food(Field& field, Food& food)
{
	if (!food.food_flag)//���� ��� ��� � ������ �� �������� ������������� �������
	{
		do
		{
			generate_food(field, food);

		} while (field.field[food.food_y][food.food_x] != field_symbol);

		field.field[food.food_y][food.food_x] = food_symbol;

		food.food_flag = true;
	}	
}

//����������� �������� ����, ��� ������ ����� ��� (���������� ������ ��������� � ������������� ���)
void check_eating(Snake& snake, Food& food)
{
	if (snake.snake_y[0]== food.food_y && snake.snake_x[0] == food.food_x)//���������� ��� ��������� � ������������ ������
	{
		food.food_flag = false;//��� ���
		++food.score;
		snake.snake_size++; //���������� ������� ������		
	}	
}

//����������� �������� ����, ��� ������ ����������� � �������� ����
void check_snake(Field& field, Snake& snake)
{	
	if (snake.snake_x[0] == 0)
	{
		snake.snake_x[0] = field.columns - 2;
	}
	
	if (snake.snake_x[0] == field.columns - 1)
	{
		snake.snake_x[0] = 1;
	}

	if (snake.snake_y[0] == 0)
	{
		snake.snake_y[0] = field.rows - 2;
	}

	if (snake.snake_y[0] == field.rows - 1)
	{
		snake.snake_y[0] = 1;
	}
}

//�������� ����������  ����.
int check_game(Field& field, Snake& snake, Food& food)
{
	int tmp_game_on = 1;

	if (!food.food_flag && snake.snake_size == L)//���� ��� ��� � ������ ������������� �������
	{		
		tmp_game_on = 0;
		//��������� ������ �������� ��������� ��������� � ����������� �� �������� 
	}
		
	if (field.field[snake.snake_y[0]][snake.snake_x[0]] == tail_symbol) //�������� ����, ��� ������ ����������� � �������
	{
		tmp_game_on = 0;
	} 
	
	return tmp_game_on;
}

//��������� ����������������� �����, ������� ����������� �������� ������
void handle_cmd(Snake& snake, Game& game)
{
	char key;//	��� ����� ���� ������� � ����������
	char keep_direct;//	��� ���������� �������  ����������� ��������.
	DIRECTION tmp_direction;

		key = _getch();
		
		if (key == 0 || key == -32)
		{
			keep_direct = _getch();
						
			switch (keep_direct)
			{
			case up: {tmp_direction = turn_up; } break;
			case down: {tmp_direction = turn_down; } break;
			case left: {tmp_direction = turn_left; } break;
			case right: {tmp_direction = turn_right; } break;
			
			default: {tmp_direction = err; }
			}
		}
		else
		{
			switch (key = toupper(key))
			{
			case s_right: {tmp_direction = turn_right; } break;
			case s_left: {tmp_direction = turn_left; } break;
			case s_up: {tmp_direction = turn_up; } break;
			case s_down: {tmp_direction = turn_down; } break;
			case s_out: {game.game_on = 0; } return;//������ (����������)
			case esc: {game.game_on = 0; } return;
				break;
			default: {tmp_direction = err; }
			}
		}
		if (tmp_direction != err)
		{
			switch (snake.direction)
			{
			case turn_up://����������, ����� ��������, ����� �����������������
			{
				if (tmp_direction == turn_down) { snake.direction = turn_up; }
				else {snake.direction = tmp_direction; }
			} break;
			case turn_down:
			{
				if (tmp_direction == turn_up) { snake.direction = turn_down; }
				else { snake.direction = tmp_direction; }
			} break;
			case turn_left:
			{
				if (tmp_direction == turn_right) { snake.direction = turn_left; }
				else { snake.direction = tmp_direction; }
			} break;
			case turn_right:
			{
				if (tmp_direction == turn_left) { snake.direction = turn_right; }
				else { snake.direction = tmp_direction; }
			} break;
			default: { snake.direction = tmp_direction; } break;
			}
		}
}


// ����� ���������� ��� ��������� ���� � ������� ������
void game_over(Field& field, Snake& snake, Food& food)
{
	setCursorPosition(0, 0);
	
	if(snake.snake_size<L)	field.field[snake.snake_y[0]][snake.snake_x[0]] = head_symbol;

	print_field(field, food.score);

	if (snake.snake_size == L) std::cout << "Max size! You win!" << std::endl;
	else  std::cout << "You lose!" << std::endl;
	
	std::cout << "The end!" << std::endl;

	//������ ������
	for (int i = 0; i < field.rows; i++)
	{
		delete[] field.field[i];
	}

	delete[] field.field;

}